package com.tyfspring.beans.annotation;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.TypeUtil;
import com.tyfspring.beans.aware.BeanFactoryAware;
import com.tyfspring.beans.config.InstantiationAwareBeanPostProcessor;
import com.tyfspring.beans.config.PropertyValues;
import com.tyfspring.beans.exception.BeansException;
import com.tyfspring.beans.factory.BeanFactory;
import com.tyfspring.beans.factory.ConfigurableBeanFactory;
import com.tyfspring.core.convert.ConversionService;

import java.lang.reflect.Field;

/**
 * @Description 处理@Autowired和@Value注解的BeanProcessor
 * @Author shallow
 * @Date 2023/3/26 13:33
 */

public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {

    private ConfigurableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (ConfigurableBeanFactory) beanFactory;
    }


    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        //处理@Value注解和@Autowired注解
        //1.处理@Value注解
        //反射获得对象的属性列表
        Class<?> clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //获取属性上的@Value,如果有则进行属性注入
            Value valueAnnotation = field.getAnnotation(Value.class);
            if (valueAnnotation!=null){
                Object value = valueAnnotation.value();
                value = beanFactory.resolveEmbeddedValue((String) value);

                //类型转换
                Class<?> sourceType = value.getClass();
                Class<?> targetType = (Class<?>)TypeUtil.getType(field);
                ConversionService conversionService = beanFactory.getConversionService();
                if(conversionService!=null){
                    if (conversionService.canConvert(sourceType,targetType)){
                        value = conversionService.convert(value,targetType);
                    }
                }

                BeanUtil.setFieldValue(bean,field.getName(),value);
            }

        }

        //处理@Autowired注解
        for (Field field : fields) {
            //获取属性上的@Autowired,如果有则进行属性注入
            Autowired autowiredAnnotation = field.getAnnotation(Autowired.class);
            if (autowiredAnnotation!=null) {
                Class<?> filedType = field.getType();
                String dependentBeanName = null;
                //@Autowired默认按类型注入，若按名称注入，配合Qualifier注解使用
                Qualifier qualifierAnnotation = field.getAnnotation(Qualifier.class);
                Object dependentBean = null;
                if (qualifierAnnotation!=null) {
                    dependentBeanName = qualifierAnnotation.value();
                    dependentBean = beanFactory.getBean(dependentBeanName, filedType);
                }else{
                    dependentBean = beanFactory.getBean(filedType);
                }
                BeanUtil.setFieldValue(bean,field.getName(),dependentBean);
            }
        }
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return false;
    }


}
